package utils

import (
	"encoding/binary"
	"encoding/json"
	"errors"
	"fmt"
	"net"
	"retalk/common/message"
)

//将方法关联到结构体中
type Transfer struct {
	Conn net.Conn   //连接
	Buf  [8096]byte //传输时使用的缓冲区
}

//发送消息数据
func (this *Transfer) WritePkg(data []byte) (err error) {
	//先发送一个长度给对方
	var pkgLen uint32
	pkgLen = uint32(len(data))
	binary.BigEndian.PutUint32(this.Buf[0:4], pkgLen)
	//发送长度
	n, err := this.Conn.Write(this.Buf[0:4])
	if n != 4 || err != nil {
		fmt.Println("消息长度发送失败　err=", err)
		return
	}
	fmt.Printf("消息长度为 %v \n", len(data))

	//发送data本身
	n, err = this.Conn.Write(data)
	if n != int(pkgLen) || err != nil {
		fmt.Println("conn.Write 失败：err=", err)
		//err = errors.New("写消息体错误...")
		return
	}
	return
}

//读取消息数据
func (this *Transfer) ReadPkg() (mes message.Message, err error) {
	n, err := this.Conn.Read(this.Buf[:4])
	if n != 4 || err != nil {
		fmt.Println("conn.Read err=", err)
		// err = errors.New("读消息包长度错误...")
		return
	}
	fmt.Println("读取到buf=", this.Buf[:4])
	var pkgLen uint32 //消息数据包长度
	pkgLen = binary.BigEndian.Uint32(this.Buf[:4])
	//根据消息数据包长度读取消息内容
	n, err = this.Conn.Read(this.Buf[:pkgLen])
	if n != int(pkgLen) || err != nil {
		fmt.Println("conn.Read 失败：err=", err)
		err = errors.New("读消息体错误...")
		return
	}

	//将mes反序列化
	err = json.Unmarshal(this.Buf[:pkgLen], &mes)
	if err != nil {
		fmt.Println("json.Unmarshal错误：err=", err)
		// err = errors.New("消息 json 反序列化错误...")
		return
	}
	return
}
